/**
 * Email services are automated processes that use Apex classes
 * to process the contents, headers, and attachments of inbound
 * email.
 
 This handler is designed to receive inbound emails that have been sent
 from the same salesforce.com org,  break the text body down into components that can then be used to
 inject posts and comments into a newsfeed.
 
 Reason this approach is used is so that different user contexts can be achieved via the one apex controller.
 
 */
global class inboundEmailHandler implements Messaging.InboundEmailHandler {

    global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {
        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
        // look for whether is a post or comment and process accordingly.
        if (email.subject == 'New Post') {
            // treat as a post
            String postType = getParameter('<post.Post_type__c:',email.plainTextBody);
        
            FeedPost fpost = new FeedPost();
            fpost.ParentId = getParameter('<parentId:',email.plainTextBody); // link to parent record
            fpost.Body = getParameter('<post.Name:',email.plainTextBody);
            
            // need some additional prep depending on the post type
            if (postType == 'Link') {
                // adding additional link post info
                fpost.Type = 'LinkPost';
                fpost.LinkURL = getParameter('<post.Link_URL__c:',email.plainTextBody); // per the API docs.
                fpost.Title = getParameter('<post.Name:',email.plainTextBody);
            } 
            else if (postType == 'Content') {
                // adding a content post - need to get attachment to post metadata record
                //fpost.Type = 'ContentPost'; - this is automatically done once next two parameters are set
                // get the attachment info 
                String postId = getParameter('<post.Id:',email.plainTextBody);
                Attachment attach = [Select Id,Body,ParentId,Name,ContentType from Attachment where ParentId =:postId LIMIT 1];
                        
                fpost.ContentData = attach.Body;
                fpost.ContentFileName = attach.Name;
            }
            
            // must be a plain text post - nothing additional required
            
            // need to catch the resulting id of the new feedpost on insert, and update the cObj Post record.
        
        insert fpost;    
        
        // now get the id to pin any child comments to later 
        
        List<Newsfeed> myPostFeed = [SELECT Id, Type, 
                                CreatedById, CreatedBy.FirstName, CreatedBy.LastName, CreatedDate,
                                ParentId, Parent.Name, 
                                FeedPostId, FeedPost.Body, FeedPost.Title, FeedPost.CreatedById,
                                (SELECT Id, FieldName, OldValue, NewValue 
                                        FROM FeedTrackedChanges ORDER BY Id DESC), 
                                (SELECT Id, CommentBody, CreatedDate,
                                        CreatedById, CreatedBy.FirstName, CreatedBy.LastName
                                        FROM FeedComments ORDER BY CreatedDate, ID DESC LIMIT 10)
                                FROM NewsFeed
                               WHERE feedpostid = :fpost.id
                                ORDER BY CreatedDate DESC, ID DESC
                                LIMIT 1]; 
        
        
        
        // update post record with relevant post id
        
        Chatter_Post__c pUpdate = [ Select Id, Post_Id__c from Chatter_Post__c where Name =:fpost.Body LIMIT 1];
        if (myPostFeed.size() != 0) { 
            pUpdate.Post_Id__c = myPostFeed.get(0).id;
            update pUpdate; // store the new Post Id against the Post cObj record, so comments are correctly attached in later cycles
        } 
            
        } else if (email.subject == 'New Comment') {
            // process as a Comment
            FeedComment fcomment = new FeedComment();
            fcomment.FeedItemId = getParameter('<parentId:',email.plainTextBody); // link to Post
            fcomment.CommentBody = getParameter('<CommentBody:',email.plainTextBody);
            insert fcomment;    
            System.debug('%%%%%%%%%%%%%% new comment added :'+fcomment);
        }
    return result;
    }
    
    //
    // this method returns a string contained within parameter tag within a nominated string
    //
    public static String getParameter ( String textPattern, String textString ) {
        // assumes parameter string ends with '>'
        system.debug('----------- am in the getParameter method ------------');
        system.debug('textPattern =:'+textPattern);
        Integer paramStart = textString.indexOf(textPattern) + textPattern.length();
        system.debug('paramStart =:'+paramStart);
        String temp = textString.substring(paramStart,textString.length());
        system.debug('temp string =:'+temp);
        Integer paramEnd = temp.indexOf('>');
        if (paramStart > 0 ) {
            system.debug('----------- returning parameter = '+temp.substring(0,paramEnd));
            return temp.substring(0,paramEnd).trim();
        } else {
            return '';
        }
   }
    
    
}